王子子的成长之路

sklearn学习笔记-2 数据处理

稀疏和非稀疏

在矩阵中,若数值为0的元素数目远远多于非0元素的数目时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。稀疏被称为L1,非稀疏被称为L2

2.1 数据标准化

  • 特征决定了模型的上限,算法决定了如何逼近这个上限
  • 对业务了解的越多,提出的特征越好
  • sklearn的数据处理能力现在非常强大,能处理文本、图片或更多的数据
  • 在数据量纲不一样时,需要对数据进行标准化,一般来说,涉及到梯度下降的模型,和涉及到距离的模型,都需要做数据标准化。

定义
标准化1(常用的标准化):减去一列的平均数再除以标准差,使其符合平均数为0标准差为1的高斯分布。
标准化2:压缩数据至0到1
树类模型不需要标准化。
标准化不能在训练集和测试集上分开进行(两个集的平均数和标准差不同),应当在测试集上应用训练集的标准化(减去标准化的平均数,除以标准化的标准差)。
把训练集和测试集放在一起做标准化也不是一种较好的办法,最优的办法是在训练集上做标准化,并transform到测试集中。

scale

用于针对列的数据标准化

函数
sklearn.preprocessing.scale(X,axis=0,with_mean=True,with_std=True,copy=True)
X传入数组,支持pandas数据框,axis=0按列处理,mean=True平均数接近0,std=True标准差接近1
方法
sklearn.preprocessing.StandarScaler(with_mean=True,with_std=True,copy=True)
相比方法,函数很少被用到,因为该方法没有transform接口。
当数据不以时间为顺序时,可以随机划分训练集和测试集。

随机划分数据集

from sklearn.cross_validation import train_test_split#调取切割函数  
X_train, X_test, y_train, y_test = train_test_split(df1,df['area'],train_size=0.7)   # 数据参数,数据结果,切分为测试集的比例  
# X_train是被切分为训练集的比例,X_test是被切分为测试集的比例,y相同  

在一个函数内训练两个集,目的是为了不破坏索引顺序

标准化数据1(正态数据)  
from sklearn.preprocessing import StandardScaler#调取标准化函数  
ss=StandardScaler()#创建标准化对象  
ss.fit(X_train)#以训练集训练标准化对象  
X_train_ss=ss.transform(X_train)#将训练结果应用于训练集  
X_test_ss=ss.transform(X_test)#将训练结果用于与测试集  

此时,返回的结果都是numpy形式的多维数组。
每一组的平均值无限接近于0,标准差无限接近于1。

标准化数据2(压缩数据)  
from sklearn.preprocessing import MinMaxScaler#调取压缩函数  
mms = MinMaxScaler()#创建标准化对象  
mms.fit(X_train)#依然以训练集训练标注化对象  
#...  

以上标准化方法,都是对每一列(每一个特征进行标准化)

normalize

对整个样本进行数据标准化(正则)

函数
sklearn.preprocessing.normalize(X, norm=‘12’, axis=1 ,copy=True, return_norm=False)
方法
sklearn.preprocessing.Normalizer(norm=‘12’, copy=True)

normalize针对样本,但样本间是独立的,因此该方法的transform无意义(整个样本都被转换了,单个使用时就不必transform),只会在papline中有意义。
该方法只会用于计算距离、无监督学习的聚类中使用。默认接受L2 (稠密矩阵)

from sklearn.preprocessing import  Normalizer  # 调用正则函数  
norm = Normalizer()  # 创建初始化对象  
norm.fit((X_train))  # 虽然无意义,仍需要按照标准书写  
norm.transform(X_train)  # 虽然无意义,仍需要按照标准书写  
norm.transform(X_test)  # 虽然无意义,仍需要按照标准书写  

2.2 分类值与缺失值

binarizer

用作数据二分化的分类,将一个连续性变量改为离散变量。

数据离散化的好处:数据存储空间小,并且因为0不参与运算(相加为原值,相乘为0)使运算速度非常快。
离散化也能较好的处理缺失值,可以将缺失值单独的形成一个特征,出现缺失值的行为1.
逻辑回归非常偏好离散化完成的数据

from sklearn.preprocessing import Binarizer#调取二分数据函数  
bi = Binarizer(548)#创建对象定义分类标准,大于该值会被分为1,小于为0  
DC_bi=bi.fit_transform(df['DC'])#调用对象进行分类  

当使用一列表示象征性的分类时,不要使用数字,因为程序sklearn会认为该特征的大小和顺序是有意义的,正确的做法是对少量参数进行稀释矩阵。
构建稀疏矩阵:skleran的OneHotEncoder非常不好用还容易报错,因此我们使用pandas的get_dummies()。

pd.get_dummies(data=df, columns=['month','day','DC_bi'])  

缺失值

缺失值有时是真实存在的,缺失是存在意义的,并且当数据不够大时,删除缺失值只会浪费样本。
因此,更好的方式是填充缺失值,填充方式尽量通过业务的理解来进行填充。

from sklearn.preprocessing import Imputer#调用填充缺失值函数,该函数默认填充平均值  
im=Imputer()#创建对象  
dfna=im.fit_transform(df['DC_na'])#选出需要填充的列并输出列  

Tips:
1. 这里有错误,训练出来的列长度并不等于原来的长度,因此还是寄希望于pandas来处理
2. sklearn有些函数不支持缺失值或无限大、无限小的数据,因此通过pandas将此类数据设为缺失值,并且一次性的处理它。
3. 缺失值可以使用-999代替。

2.3 变量选择

特征选取

共线性特征,只保留一个就可以,可以用皮尔逊共线测试一下。
当特征过多时,只保留重要特征,删除掉不重要的参数也可以提高准确率。

针对稀疏矩阵判断特征的两种方式:
1. 使用lasso来选择特征

from sklearn.linear_model import Lasso  # 从线性模型这种调取能判断参数重要性的函数lasso()  
lasso = Lasso()  # 创建对象  
lasso.fit(xdata,ydata)  #   fit不接受缺失值,使用前记得填充缺失值为-999。第一个参数为参数df,第二个参数为结果df  
print(lasso.coef_)  # 打印特征重要程度,可以删除无限接近于0的特征  

所有的稀疏矩阵类型,都可以放入此函数进行判断。

  1. 使用featureselect来选择特征:

    from sklearn.feature_selection import SelectFromModel  # 调用参数选择模型  
    model = SelectFromModel(lasso)  # 创建对象并直接传入模型,相当于省略了fit步骤  
    model.fit_transform()  # 无意义,为了是一个popline,另外sklearn不接受异常值,这里因为极大和极小值的存在,会报错。  

支持LR回归,简单线性回归
当特征是连续性,我们希望方差越大越好

特诊判断

基于树形模型对特征进行判断:

from sklearn.ensemble import RandomForestRegressor#从随机森林库中调取树类特征选择函数  
rf = RandomForestRegressor()#创建对象  
rf.fit(xdata,ydata)#训练模型,第一个参数为参数df,第二个参数为结果df  
print(rf.feature_importances_)#打印特征重要程度,数值越接近于0,意义越小  

提到的pandas相关操作

.head():读取前五行数据
df.loc[ : ,x:y]:索引选取x到y列的数据
df[0, : ]维度转换
pd.cut(df[‘’],n):将padans中的一列均匀的切分成n份,返回的值是一个字符串。
pd.get_dummies(data, prefix = None, prefix_sep = ’_’, dummy_na = False, columns=None, sparse = False, drop_first = False):函数接受一个df表格以及使用columns选取的列,函数会删除原来的列并对其进行稀疏化矩阵的扩充,使其变为0/1形式,返回一个重新构建好的df表格。
df.loc[df[‘DC’]>=600,‘DC_na’] = np.nan :对df行中的DF列大于等于600的,新建一列设为NaN。
df.replace(np.inf,np.nan):替换过大值为NaN